package com.ccExcelUtil.util;

import javax.validation.ConstraintValidatorContext;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author xiaozhao
 */
public class ViolationUtils{

    private static ConstraintValidatorContext context;

    public ViolationUtils(ConstraintValidatorContext context) {
        ViolationUtils.context = context;
    }

    public static <T> boolean  addViolation(SFunction<T, String> column, String message) {
        Method writeReplaceMethod;
        try {
            writeReplaceMethod = column.getClass().getDeclaredMethod("writeReplace");
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        // 从序列化方法取出序列化的lambda信息
        boolean isAccessible = writeReplaceMethod.isAccessible();
        writeReplaceMethod.setAccessible(true);
        SerializedLambda serializedLambda;
        try {
            serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(column);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        writeReplaceMethod.setAccessible(isAccessible);

        // 从lambda信息取出method、field、class等
        String fieldName = serializedLambda.getImplMethodName().substring("get".length());
        fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
        Field field;
        try {
            field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
        } catch (ClassNotFoundException | NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
        String name = field.getName();
        // 从field取出字段名，可以根据实际情况调整
        context.buildConstraintViolationWithTemplate(message).addPropertyNode(name).addConstraintViolation();
        return false;
    }

    public static boolean  addViolation(String columnName, String message) {
        context.buildConstraintViolationWithTemplate(message).addPropertyNode(columnName).addConstraintViolation();
        return false;
    }
}
